/***************************************************************************
 *                                                                         *
 *   This file is part of the Fotowall project,                            *
 *       http://code.google.com/p/fotowall                                 *
 *                                                                         *
 *   Copyright (C) 2007-2009 by Enrico Ros <enrico.ros@gmail.com>          *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 * ----------------------------------------------------------------------- *
 *																		   *
 *	Modifications for FotoKinect, Spring 2011 by Gianna Badiali,		   *
 *                                                   Gabriel Fernandez,	   *
 *                                                   Kelsey Tripp, and     *
 *                                                   Sam Swarr             *
 *																		   *
 ***************************************************************************/

#ifndef __Desk_h__
#define __Desk_h__

#include <QGraphicsScene>
#include <QDataStream>
#include <QPainter>
#include <QPixmap>
#include <QRect>
#include <QLabel>
#include <QTime>
#include <QDomElement>
#include <qset>
#include <QLineF>
#include "CroppingWidget.h"
#include <devices/GestureEvent.h>

class AbstractContent;
class AbstractConfig;
struct PictureEffect;
class ColorPickerItem;
class HighlightItem;
class PictureContent;
class QTimer;
class TextContent;

class Desk : public QGraphicsScene
{
    Q_OBJECT
    public:
        friend class XmlRead;
        friend class XmlSave;
        Desk(QObject * parent = 0);
        ~Desk();

        // color selector
        void showColorSelector();
        void hideColorSelector();
        void updateColorSelector(QPoint pos);
        void updateColorSelectorHue(QPoint pos);
        void updateColorSelectorValue(QPoint pos);
        bool withinColorSelector(QPoint pos);
        void resetColorSelector();

        // add content
        void addPictures(const QStringList & fileNames);
        bool containsPictures() { return !m_content.empty(); }

        // delete content
        bool deletePicture();

        // resizing scene
        void resize(const QSize & size);

        // cropping content
        void beginCropMode(CroppingWidget &croppingWidget);
        bool cropPicture(QRect cropSelection);

        // saving and loading
        void toXml(QDomElement &de) const;
        void fromXml(QDomElement &de);

        // rendering the Desk, but not the invisible items
        void renderVisible(QPainter * painter, const QRectF & target = QRectF(), const QRectF & source = QRectF(), Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);
        QImage renderedImage(const QSize & size, Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);

        // selection and hover
        bool slotSelect(InputPoint p);
        void slotDeselect(InputPoint p);
        void slotCheckHover(QList<QPoint> points);

    protected:
        void drawBackground( QPainter * painter, const QRectF & rect );
        void drawForeground( QPainter * painter, const QRectF & rect );

    private:
        void initContent(AbstractContent * content, const QPoint & pos);
        void setBackContent(AbstractContent * content);
        PictureContent * createPicture(const QPoint & pos);

        // content and desk elements
        QList<AbstractContent *> m_content;
        QList<AbstractConfig *> m_configs;
        QList<HighlightItem *> m_highlightItems;
        AbstractContent * m_backContent;
        ColorPickerItem * m_colorPicker;
        bool m_backGradientEnabled;
        Qt::AspectRatioMode m_backContentRatio;
        QSize m_size;
        QRectF m_rect;
        QPixmap m_backTile;
        QPixmap m_backCache;
        QList<QGraphicsItem *> m_markerItems;   // used by some modes to show information items, which won't be rendered

        // current selections
        AbstractContent *m_selected;
        AbstractContent *m_cropSelection;
        QSet<int> m_inputsSelect;
        // saved state data for transformations
		bool m_isSaved, m_isPrepared;
        QPointF m_savedPos;
        QRectF m_savedRect;
        qreal m_savedRotationX;
        qreal m_savedRotationY;
        qreal m_savedRotationZ;
        QTransform m_savedTransform;
        double m_savedWidth;
        double m_savedHeight;
        QColor m_lastColor;

        QLineF m_line1;
        QPointF m_diff;


    Q_SIGNALS:
        void backModeChanged();
        void showPropertiesWidget(QWidget * widget);
        void signalInputStateChange(int id, InputState state);


    public Q_SLOTS:
        void slotMove(double dx, double dy);
        void slotScale(double perc);
        void slotRotate(double angle, Qt::Axis axis);
        void slotSaveState();
		void slotUnsave();
        void slotPrepareTransform(qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2);
        void slotTransform(qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2);
        void slotFlip(int i);  // 0: HORZ, 1:VERT
        void slotUpdateLastColor();

    private Q_SLOTS:
        friend class AbstractConfig; 
        friend class PixmapButton;
        void slotSelectionChanged();
        void slotConfigureContent(const QPoint & scenePoint);
        void slotBackgroundContent();
        void slotStackContent(int);
        void slotDeleteContent();
        void slotDeleteConfig(AbstractConfig * config);
        void slotFlipHorizontally();
        void slotFlipVertically();

        // background/foreground
        void slotForeColorChanged();
        void slotGradColorChanged();
        void slotBackContentChanged();
};

#endif
